<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\Access\User\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\SoftDeletes;

class Ogz extends Model
{
    use SoftDeletes;

    protected $table = 'ogz';
    protected $fillable = ['pid','name','description','sort','contact'];
    protected $primaryKey = 'id';

    public $timestamps = true;

    protected $dates = ['deleted_at'];
    //当前机构下的所有子机构ID
    protected  static $subOgzIds =[];
    //机构联系人一对一
    public function hasOneUser(){

        return $this->hasOne('App\Models\User\User','id','contact');
    }

    //机构app一对多
    public function hasManyApp(){
        return $this->hasMany('App\Models\App','','id');
    }

    //机构和用户多对多
    public function users(){
        return $this->belongsToMany('App\Models\Access\User\User','assigned_ogzs','ogz_id','user_id');
    }

    /**
     * 列表信息
     * @param string $field
     * @param array $where
     * @param bool $getCount
     * @param bool $isTree 搜索不显示tree
     * @return mixed
     */
    public static function getList($field='*',$where=null,$getCount=false,$isTree = true){
        $builder = DB::table('ogz as o')
            ->select($field)
            ->leftJoin('users as u','o.user_id','=','u.id');
        //独立查询
        $iddQuery = true;
        if ($where && is_array($where)) {
                if (isset($where[0]) && $where[0]) {
                    if ($where[0][1] == '!=') {
                        $builder = $builder->whereNotNull($where[0][0]);
                    }
                    if ($where[0][1] == '==') {
                        $builder = $builder->whereNull($where[0][0]);
                    }
                    //分组查询
                    if (isset($where[1]) && $where[1]) {
                        $iddQuery = false;
                        $builder = $builder->where(function ($query) use ($where) {
                            $query->where($where[1][0][0], $where[1][0][1], $where[1][0][2])->orWhere($where[1][1][0], $where[1][1][1], $where[1][1][2]);
                        });
                    }
                }
                if (isset($where[1]) && $where[1] && $iddQuery) {
                    $builder = $builder->where($where[1][0][0], $where[1][0][1], $where[1][0][2]);
                    //循环构建器
                    $_depth = self::array_depth($where[1]);
                    for ($i = 1; $i < $_depth; $i++) {
                        $builder = $builder->orwhere($where[1][$i][0], $where[1][$i][1], $where[1][$i][2]);
                    }
                }
        }
        //全局条件
        if (isset($where[2]) && $where[2])
            $builder = $builder->whereIn($where[2][0],$where[2][1]);
        if ($getCount){
            return $builder->count();
        } else {
            //同级别排序
            $builder = $builder->orderBy('sort','desc');
            $sourceItems = $builder->get();
            //使用了treeTable
            //搜索取消tree
            if (!$isTree){

                return $sourceItems;
            }
            return self::getTree($sourceItems,(new Collection));
        }

    }

    /**
     * 无限极递归tree
     * @param collection $sourceItems源数据
     * @param collection $targetItems目标数据，为了父子级别对应
     * @param int $pid父id
     * @param string $str父子级别标识符号
     * @param int $level第几级
     * @return array
     */
    public static function getTree ($sourceItems,$targetItems,$pid=0,$str='',$level=0) {
        //'├─ '
        //'├─├─  '
        // $str .= '├─';
        $level++;
        foreach ($sourceItems as $k => $v) {
            if($v->pid == $pid){
                $v->name = $str . $v->name;
                $v->level = $level;
                $targetItems[] = $v;
                self::getTree($sourceItems, $targetItems, $v->id,$str,$level);
            }
        }
        return $targetItems;
    }

    /**
     * 获取子集,深度数组
     * @param $pid指定父级id
     * @param $withTrash=false只取正常的true取所有
     * @return array
     */
    public static function getChild ($pid=0,$fields='*',$withTrash=true){
        $builder = DB::table('ogz')->select($fields)->where('pid','=',$pid);
        //sort order
        $builder = $builder->orderBy('sort','desc');
        if (!$withTrash){

            $builder = $builder->whereNull('deleted_at');
        }
        $res[] = intval($pid);
        $data = $builder->get();

        if (!empty($data)){

            foreach ($data as $key => $item){
                $res[] =$item->id;
                $temp = self::getChild($item->id,$fields,$withTrash);

                if (!$temp->isEmpty()){

                    $item->child = $temp;
                }

            }
        }
        self::$subOgzIds[]=$res;
        $data->ids=self::$subOgzIds;
        return $data;
    }

    /**
     * 获取结果，非层次级
     */
    public static function getChildNoLayer ($data){
        $result = [];

        foreach ($data as $item){

            $result[] = $item->id;
            if (isset($item->child)){
                $result = array_merge($result,self::getChildNoLayer($item->child));

            }

        }
        return $result;
    }
    /**
     * 检索是否有子节点
     * @param $pid =0
     * @return mixed
     */
    public function hasChild ($pid = 0) {
        $data = $this->where('pid', '=', $pid)->get();
        if ($data->isEmpty()){
            return false;
        }
        return true;
    }

    /**
     * 获取父级
     * @param $pid
     * @return mixed
     */
    public static function getParent ($pid,$withTrash=false) {
        $res = [];
        $builder = DB::table('ogz')->select(['id','pid'])->where('id','=',$pid);

        if (!$withTrash){

            $builder = $builder->whereNull('deleted_at');
        }
        $data = $builder->first();
        if (!empty($data)){

            $res[] = $data->id;
            if ($data->pid != 0){

                $res = array_merge($res,self::getParent($data->pid,$withTrash));
            }
        }

        return $res;

    }

    /**
     * 数组维度
     * @param $array
     * @return int
     */
    private static function array_depth($arry) {
        if(!is_array($arry)) return 0;
        $max_depth = 1;
        foreach ($arry as $value) {
            if (is_array($value)) {
                //递归深度
                $depth = self::array_depth($value) + 1;

                if ($depth > $max_depth) {
                    $max_depth = $depth;
                }
            }
        }
        return $max_depth;
    }

    /**
     * 插入记录
     * @param array $data
     * @return bool
     */
    public static function insertRow($data){

        if (empty($data))
            return false;

        return DB::table('ogz')->insert($data);

    }

    /**
     * 修改记录
     * @param array $where
     * @param array $data
     * @return bool
     */
    public static function updateRow($where,$data){

        if (empty($data))
            return false;

        return DB::table('ogz')
            ->where($where[0],$where['1'])
            ->update($data);

    }

    /**
     * 删除记录
     * @param array $request
     * @param array $data
     * @return bool
     */
    public function deleteRow($request){
        if (empty($request->id)){
            throw new \Exception('非法操作');
        }
        //有子集不能删除
        if ($this->hasChild($request->id)){
            throw new \Exception('该机构下含有子级，请先禁用子级');
        }
        $ogz = $this->find($request->id);
        //避免用户查不到机构
        if ($ogz->users()->count() > 0){
            throw new \Exception('该机构下有用户，请勿禁用');
        }
        if ($ogz->hasManyApp()->count() > 0){
            throw new \Exception('该机构下有企业应用，请勿禁用');
        }
        $ogz->delete();
        if ($ogz->trashed()) {
            return true;
        }else{

            throw new \Exception('组织机构禁用失败');
        }
    }
    /**
     * 激活
     * @param mixed $request
     * @return bool
     */
    public static function activeRow($request){
        //超级管理员不存在这操作
        if (intval($request->id)===1)
            return false;
        $ogz = Ogz::withTrashed()->find($request->id);
        //避免禁用用户二次进入
        if ($ogz){
            $ogz->deleted_at = NULL;
            if ($ogz->save()){
                return true;
            }
        }
        return false;

    }

    /**
     * 获取全部Id
     */
    public static function getAllIds(){

        return Ogz::select('id')->get()->toArray();
    }
    /**
     * getChild1
     * @param int $pid
     * @param bool $withTrash
     * @return mixed

     */
    public static function getChild1 ($pid=0,$withTrash=false){
        $res = [];
        $builder = DB::table('ogz')->select('id')->where('pid','=',$pid);

        if (!$withTrash){

            $builder = $builder->whereNull('deleted_at');
        }
        $res[] = $pid;
        $data = $builder->get();

        if (!empty($data)){

            foreach ($data as $key => $item){
                $res[] =$item->id;
                $temp = self::getChild1($item->id,false);

                if (!$temp->isEmpty()){
//                    foreach ($temp as $i){
//                        $res[] =$i->id;
//                    }
                    $item->child = $temp;
                }

            }
        }
        self::$subOgzIds[]=$res;
        $data->ids=self::$subOgzIds;
        return $data;
    }
    /**
     * 根据联系人查询
     * 一个机构对应多个联系人
     * @param integer $Uid
     * @return array $ogz
     */
    public static function getOgzByUser ($Uid){

        $fields = ['id','pid','name','description','sort'];
        //取消已禁用的数据
        $setWhere = 'find_in_set('.intval($Uid).',user_id) and deleted_at is NULL';
        $ogz = DB::table('ogz')->select($fields)->whereRaw($setWhere)->get();

        return $ogz;
    }
    /**
     * 子机构对应深度
     * @param array $children
     * @return array $childLevel
     */
    public static function getChildLevel ($children){
        $childLevel = [];
        foreach ($children as $k => $v){
            //get parent id
            $pid = DB::table('ogz')->where(['id'=>$v])->value('pid');

            $parentOgz = Ogz::getParent($pid);
            if ($parentOgz){
                $level = count($parentOgz) + 1;
            } else {
                $level = 1;
            }
            $childLevel[$v] = $level;
        }
        return $childLevel;
    }
    /**
     * 获取机构名字
     * @param $id
     * @return string $name
     */
    public static function getName ($id) {
        $name = '';
        if (intval($id))
            $name = self::where(['id'=>$id])->value('name');
        return $name;
    }

    /**
     * 获取不同深度信息
     * @param int $deep
     * @param string $column='id'
     * @return array
     */
    public static function getByDeep ($deep,$column='id') {
        $ret = [];
        $deepInfo = self::where(['deep'=>$deep])->select(['id','pid','user_id','ogz_ids'])->get();
        $ret = $deepInfo->pluck($column)->toArray();
        return $ret;
    }
    /**
     * 根据pid获取节点深度
     * @param int $pid
     * @return int
     */
    public static function getDeepByPid ($pid) {
        $deep = 0;
        if (is_int($pid)) {

            $deep = self::where(['pid'=>$pid])->value('deep');
        }
        return $deep;
    }

    /**
     * 根据ids查询deeps
     * @param array $ids
     * @return array
     */
    public static function getDeepsByIds ($ids) {
        $ret = [];
        if (is_array($ids)){

            $deepInfo = self::whereIn('id',$ids)->select(['id'])->get();
            $ret = $deepInfo->pluck('id')->toArray();
        }
        return $ret;
    }

    /**
     * 查询最大深度
     */
    public static function getBigestDeep () {
        return self::orderBy('deep','desc')->value('deep');
    }

    /**
     * 获取指定字段数据
     * @param array $field
     * @param array $where
     * @param bool $trash=false
     * @return array
     */
    public static function getCollectWithSel ($field,$where,$trash=false){
        $ret = [];
        if ($field && $where) {
            $builder = static::select($field);
            if ($trash) {
                $builder = $builder->onlyTrashed();
            }
            $ret = $builder->whereIn('id',access()->hasOgzs())->where($where)->get();
        }
        return $ret;
    }
    /**
     * 获取板块公司子公司信息
     * @param int $pid
     * @return array
     */
    public static function getNotTopInfo (int $pid) {
        $res = [];

        $where['id'] = $pid;

        $data = self::select(['id','pid','name'])->where($where)->first();
        if ($data){

            $res[] = $data->toArray();
            if ($data->pid > 0 && $data->pid != $data->id){

                return array_merge($res,self::getNotTopInfo($data->pid));
            }
        }

        return $res;

    }
}
